(function($) {
    var uiWindowClasses =
    'ui-window ' +
    'ui-widget ' +
    'ui-widget-content ' +
    'ui-corner-all ';
    
    $.ui.draggable.prototype._mouseStart = function(event) {
        var o = this.options;

        if(this.element.find(".ui-draggable-dragging").length != 0){
            return false;
        }

        //Create and append the visible helper
        this.helper = this._createHelper(event);

        //Cache the helper size
        this._cacheHelperProportions();

        //If ddmanager is used for droppables, set the global draggable
        if($.ui.ddmanager)
            $.ui.ddmanager.current = this;

        /*
         * - Position generation -
         * This block generates everything position related - it's the core of draggables.
         */

        //Cache the margins of the original element
        this._cacheMargins();

        //Store the helper's css position
        this.cssPosition = this.helper.css("position");
        this.scrollParent = this.helper.scrollParent();

        //The element's absolute position on the page minus margins
        this.offset = this.positionAbs = this.element.offset();
        this.offset = {
            top: this.offset.top - this.margins.top,
            left: this.offset.left - this.margins.left
        };

        $.extend(this.offset, {
            click: { //Where the click happened, relative to the element
                left: event.pageX - this.offset.left,
                top: event.pageY - this.offset.top
            },
            parent: this._getParentOffset(),
            relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
        });

        //Generate the original position
        this.originalPosition = this.position = this._generatePosition(event);
        this.originalPageX = event.pageX;
        this.originalPageY = event.pageY;

        //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
        (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));

        //Set a containment if given in the options
        if(o.containment)
            this._setContainment();

        //Trigger event + callbacks
        if(this._trigger("start", event) === false) {
            this._clear();
            return false;
        }

        //Recache the helper size
        this._cacheHelperProportions();

        //Prepare the droppable offsets
        if ($.ui.ddmanager && !o.dropBehaviour)
            $.ui.ddmanager.prepareOffsets(this, event);

        this.helper.addClass("ui-draggable-dragging");
        
        this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position

        return true;
    };
    
$.widget("ui.window", {
    options: {
        name:       null,
        containment:null,
        title:      '',
        position:   'center',
        alpha:      1,
        dragAlpha:  0.8,
        zIndex:     1,
        width:      200,
        height:     'auto',
        maxHeight:  false,
        maxWidth:   false,
        minHeight:  200,
        minWidth:   200,
        draggable:  true,
        resizable:  true,
        isTitlebar: true,
        autoOpen:   false,
        autoTop:    true,
        alwayTop:   false,
        styleClass: '',
        winStyle:   4,
        showAnim:   null,
        hideAnim:   null,
        borderStyle:null,
        closeText:  'close',
        maxboxText: 'max',
        minboxText: 'min',
        closeOnEscape: true
        },
    //--------------------------------------------------------------------
    open: function(){
        if (this._isOpen) { 
            return; 
        }
        var self = this,
            options = self.options,
            uiWindow   = self.uiWindow;
            
        uiWindow.appendTo(this.appendContainment);
        self._size();  
        self.moveToTop();
        
        // set focus to the first tabbable element in the content area or the first button
        // if there are no tabbable elements, set focus on the window itself
        $([])
            .add(uiWindow.find('.ui-window-content :tabbable:first'))
            .add(uiWindow)
            .filter(':first')
            .focus();
            
        self._trigger('open');
        self._isOpen = true;

        return self;
    },
    //--------------------------------------------------------------------
    close: function(event){
        var self = this,
            maxZ;
        
        if (false === self._trigger('beforeClose', event)) {
            return;
        }

        self.uiWindow.unbind('keypress.ui-windows');

        self._isOpen = false;

        self.uiWindow.hide(self.options.hideAnim, function() {
            self._trigger('close', event);
        });
        
        $(this).find('a.ui-window-titlebar-close').each(function(i){
            $(this).trigger('click');
        })
        
        return self;
    },
    //--------------------------------------------------------------------
    destroy: function(){
        var self = this;
        
        self.uiWindow.hide();
        self.element
            .unbind('.window')
            .removeData('window')
            .removeClass('ui-window-content ui-widget-content')
            .hide().appendTo(this.appendContainment);
        self.uiWindow.remove();

        if (self.originalTitle) {
            self.element.attr('title', self.originalTitle);
        }

        return self;
    },
    //--------------------------------------------------------------------
    isOpen: function(){
        return this._isOpen;
    },
    //--------------------------------------------------------------------
    widget: function() {
        return this.uiWindow;
    },
    //--------------------------------------------------------------------
    moveToTop: function(event){
        var self = this,
            options = self.options,
            saveScroll;
        
        if (!options.autoTop) {
            return self._trigger('focus', event);
        }
        
        if( event && event == 'internal'){
        }else if( !event || !event.target || 
            (event.target.className.indexOf('ui-window-title') == -1 &&
            event.target.className.indexOf('ui-resizable-handle') == -1 ) )
        {
            return self;
        }
        var zIndexArrayObj = new Array();
        var zIndexArrayIdx = new Array();
        $(this.uiWindow).parent('div').find('.ui-window').each(function(i){
           zIndexArrayIdx[i]=$(this).css('z-index');
           zIndexArrayObj[i]=$(this);
           if($(this).find('.ui-window-content').first().attr('id') == self.options.name)
           {
               if( self.options.alwayTop ){
                   zIndexArrayIdx[i]=9999;
               }
               else{
                   zIndexArrayIdx[i]=1000;
               }
           }
        });
        
        var tmpZIndex   = 0;
        var tmpZIndexObj= null;
        for (var i=0; i< zIndexArrayIdx.length; i++ )
        {
            for(var j=i+1; j< zIndexArrayIdx.length; j++ )
            {
                if( zIndexArrayIdx[i] > zIndexArrayIdx[j] )
                {
                    tmpZIndex           = zIndexArrayIdx[i];
                    zIndexArrayIdx[i]   = zIndexArrayIdx[j];
                    zIndexArrayIdx[j]   = tmpZIndex;
                    tmpZIndexObj        = zIndexArrayObj[i];
                    zIndexArrayObj[i]   = zIndexArrayObj[j];
                    zIndexArrayObj[j]   = tmpZIndexObj;
                }
            }
        }
        for (var i=0; i< zIndexArrayIdx.length; i++ )
        {
            if(  zIndexArrayIdx[i] != 9999 ){
                zIndexArrayObj[i].css('z-index', i);
            }
            else{
                zIndexArrayObj[i].css('z-index', 9999);
            }
        }

        //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
        //  http://ui.jquery.com/bugs/ticket/3193
        saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
        self.element.attr(saveScroll);
        self._trigger('focus', event);

        return self;
    },
    //--------------------------------------------------------------------
    _create: function(){
        this.originalTitle  = this.element.attr('title');
        this.normalWidth     = 0;
        this.normalHeight    = 0;
        this.normalPosX      = 0;
        this.normalPosY      = 0;
        this.normalHeightShow= 0;
        this.maxboxRightPos  = 0;
        this.winStyleState   = 'normal';
        this.appendContainment  = null;
        
        if( this.options.containment ){
            if( typeof this.options.containment == 'string' && $(this.options.containment) ||
                typeof this.options.containment == 'object' )
            {
                this.appendContainment   = this.options.containment;
            }else{
               this.appendContainment    = 'body';
            }
        }else{
            this.appendContainment    = 'body';
        }
        
        var self = this,
            options = self.options,

            title = options.title || self.originalTitle || '&#160;',
            titleId = $.ui.window.getTitleId(self.element),

            uiWindow = (self.uiWindow = $('<div></div>'))
                .appendTo(this.appendContainment)
                .hide()
                .addClass(uiWindowClasses + options.styleClass)
                .css({
                    zIndex: options.alwayTop?9999:options.zIndex,
                    opacity: options.alpha
                })
                // setting tabIndex makes the div focusable
                // setting outline to 0 prevents a border on focus in Mozilla
                .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
                    if (options.closeOnEscape && event.keyCode &&
                        event.keyCode === $.ui.keyCode.ESCAPE) {
                        
                        self.close(event);
                        event.preventDefault();
                    }
                })
                .attr({
                    role: 'window',
                    'aria-labelledby': titleId
                })
                .mousedown(function(event) {
                    self.moveToTop(event);
                }),

            uiWindowContent = self.element
                .show()
                .removeAttr('title')
                .addClass(
                    'ui-window-content ' +
                    'ui-widget-content')
                .appendTo(uiWindow),

            uiWindowTitlebar = (self.uiWindowTitlebar = $('<div></div>'))
                .addClass(
                    'ui-window-titlebar ' +
                    'ui-widget-header ' +
                    'ui-corner-all ' +
                    'ui-helper-clearfix'
                )
                .prependTo(uiWindow),

            //-----------------------------------------------------------------------
            // close button in title bar
            //-----------------------------------------------------------------------
            uiWindowTitlebarClose = $('<a href="#"></a>')
                .addClass(
                    'ui-window-titlebar-close ' +
                    'ui-corner-all'
                )
                .attr('role', 'button')
                .hover(
                    function() {
                        uiWindowTitlebarClose.addClass('ui-state-hover');
                    },
                    function() {
                        uiWindowTitlebarClose.removeClass('ui-state-hover');
                    }
                )
                .focus(function() {
                    uiWindowTitlebarClose.addClass('ui-state-focus');
                })
                .blur(function() {
                    uiWindowTitlebarClose.removeClass('ui-state-focus');
                })
                .click(function(event) {
                    self.close(event);
                    return false;
                })
                .appendTo(uiWindowTitlebar),

            uiWindowTitlebarCloseText = (self.uiWindowTitlebarCloseText = $('<span></span>'))
                .addClass(
                    'ui-icon ' +
                    'ui-icon-closethick'
                )
                .text(self.options.closeText)
                .appendTo(uiWindowTitlebarClose),
           
            //-----------------------------------------------------------------------
            // max button in title bar
            //-----------------------------------------------------------------------
            uiWindowTitlebarMaxBox = $('<a href="#"></a>')
                .addClass(
                    'ui-window-titlebar-maxbox ' +
                    'ui-corner-all'
                )
                .attr('role', 'button')
                .hover(
                    function() {
                        uiWindowTitlebarMaxBox.addClass('ui-state-hover');
                    },
                    function() {
                        uiWindowTitlebarMaxBox.removeClass('ui-state-hover');
                    }
                )
                .focus(function() {
                    uiWindowTitlebarMaxBox.addClass('ui-state-focus');
                })
                .blur(function() {
                    uiWindowTitlebarMaxBox.removeClass('ui-state-focus');
                })
                .click(function(event) 
                {
                    if( self.winStyleState == 'max' )
                        self.restore();
                    else
                        self.maximize();
                    return false;
                })
                .appendTo(uiWindowTitlebar),
                
            uiWindowTitlebarMaxBoxText = (self.uiWindowTitlebarMaxBoxText = $('<span></span>'))
                .addClass(
                    'ui-icon ' +
                    'ui-icon-maxboxthick'
                )
                .text(self.options.maxboxText)
                .appendTo(uiWindowTitlebarMaxBox),
                
            
            //-----------------------------------------------------------------------
            // min button in title bar
            //-----------------------------------------------------------------------
            uiWindowTitlebarMinBox = $('<a href="#"></a>')
                .addClass(
                    'ui-window-titlebar-minbox ' +
                    'ui-corner-all'
                )
                .attr('role', 'button')
                .hover(
                    function() {
                        uiWindowTitlebarMinBox.addClass('ui-state-hover');
                    },
                    function() {
                        uiWindowTitlebarMinBox.removeClass('ui-state-hover');
                    }
                )
                .focus(function() {
                    uiWindowTitlebarMinBox.addClass('ui-state-focus');
                })
                .blur(function() {
                    uiWindowTitlebarMinBox.removeClass('ui-state-focus');
                })
                .click(function(event) {
                    self.minimize();
                    return false;
                })
                .appendTo(uiWindowTitlebar),
                
            uiWindowTitlebarMinBoxText = (self.uiWindowTitlebarMinBoxText = $('<span></span>'))
                .addClass(
                    'ui-icon ' +
                    'ui-icon-minboxthick'
                )
                .text(self.options.minboxText)
                .appendTo(uiWindowTitlebarMinBox),
                
                
            uiWindowTitle = $('<span></span>')
                .addClass('ui-window-title')
                .attr('id', titleId)
                .html(title)
                .prependTo(uiWindowTitlebar);
            this.uiWindowTitle  = uiWindowTitle;
                
        uiWindowTitlebar.bind("dblclick", function(){
            self.minimize();
        });
        
        this.uiWindowContent        = uiWindowContent;
        this.uiWindowTitlebar       = uiWindowTitlebar;
        this.uiWindowTitlebarMinBox = uiWindowTitlebarMinBox;
        this.uiWindowTitlebarMaxBox = uiWindowTitlebarMaxBox;
        this.uiWindowTitlebarClose  = uiWindowTitlebarClose;

        if( options.borderStyle ){
            uiWindow.css('boder', options.borderStyle);
        }
        //handling of deprecated beforeclose (vs beforeClose) option
        //Ticket #4669 http://dev.jqueryui.com/ticket/4669
        //TODO: remove in 1.9pre
        if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
            options.beforeClose = options.beforeclose;
        }

        uiWindowTitlebar.find("*").add(uiWindowTitlebar).disableSelection();

        if( !self.options.isTitlebar ){
            uiWindowTitlebar.hide();
        }else{
            var hasMin  = true;
            var hasMax  = true;
            if( parseInt(self.options.winStyle & 1) == 0 ){
                uiWindowTitlebarMinBox.hide();
                hasMin  = false;
            }
            if( parseInt(self.options.winStyle & 2) == 0 || this.appendContainment == 'body'){
                uiWindowTitlebarMaxBox.hide();
                hasMax  = false;
                if( hasMin == true ){
                    uiWindowTitlebarMinBox.css('right', uiWindowTitlebarMaxBox.css('right'));
                }
            }
            if( parseInt(self.options.winStyle & 4) == 0 ){
                uiWindowTitlebarClose.hide();
                if( hasMax == true ){
                    if( hasMin == true ){
                        uiWindowTitlebarMinBox.css('right', uiWindowTitlebarMaxBox.css('right'));
                    }
                    uiWindowTitlebarMaxBox.css('right', uiWindowTitlebarClose.css('right'));
                }else{
                    if( hasMin == true ){
                        uiWindowTitlebarMinBox.css('right', uiWindowTitlebarClose.css('right'));
                    }
                }
            }
        }
        if (options.draggable && $.fn.draggable) {
            self._makeDraggable();
        }
        if (options.resizable && $.fn.resizable) {
            self._makeResizable();
        }
        
        self._isOpen = false;
        if ($.fn.bgiframe) {
            uiWindow.bgiframe();
        }
    },
    //--------------------------------------------------------------------
    _init: function(){
        this.open();
        this._position(this.options.position);
        var self =  this, 
            options = self.options;
        if ( this.options.autoOpen ) {
            this.uiWindow.show(this.options.showAnim, {}, 500, function(){
                self.uiWindow.css({opacity: self.options.alpha});
            });
        }
    },
    //--------------------------------------------------------------------
    restore: function(){
        if( this.winStyleState == 'normal' )
            return;
        this._makeDraggable();
        this.winStyleState = 'normal'
        this.uiWindow.width(this.normalWidth);
        this.uiWindow.height(this.normalHeight);
        var contentOffset = this.uiWindowContent.outerHeight()-this.uiWindowContent.height();
        this.uiWindowContent.height(this.normalHeight - this.uiWindowTitlebar.outerHeight() - contentOffset);
        this.uiWindow.css('left', this.normalPosX);
        this.uiWindow.css('top', this.normalPosY);
    },
    //--------------------------------------------------------------------
    maximize: function(){
        var options         = this.options;
        var uiWindow        = this.uiWindow;
        
        if( self.winStyleState  == 'max' || this.appendContainment == 'body' )
            return;
            
        this.winStyleState  = 'max';
        this.uiWindow.draggable('destroy');
        this.moveToTop('internal');
        
        var tmpMaxWidth     = options.maxWidth;
        var tmpMaxHeight    = options.maxHeight;
        var parentWidth     = uiWindow.parent().width();
        var parentHeight    = uiWindow.parent().height();
        this.normalWidth    = uiWindow.width();
        this.normalHeight   = uiWindow.height();
        this.normalPosX     = uiWindow.position().left;
        this.normalPosY     = uiWindow.position().top;
        
        if( tmpMaxWidth == false || tmpMaxWidth > parentWidth){
            tmpMaxWidth     = parentWidth;
        }
        if( tmpMaxHeight == false || tmpMaxHeight > parentHeight){
            tmpMaxHeight    = parentHeight;
        }
        
        var offsetX         = tmpMaxWidth-(parentWidth-this.normalPosX);
        var offsetY         = tmpMaxHeight-(parentHeight-this.normalPosY);
        if( offsetX > 0 ){
            offsetX = this.normalPosX - offsetX;
            if( offsetX < 0 )offsetX = 0;
            uiWindow.css('left', this.uiWindowTitlebar.position().left + offsetX);
        }
        if( offsetY > 0 ){
            offsetY = this.normalPosY - offsetY;
            if( offsetY < 0 )offsetY = 0;
            var parentTitlebar  = this.uiWindow.parent().prev('div');
            if( parentTitlebar.is('.ui-window-titlebar') && parentTitlebar.is(':visible') )
                uiWindow.css('top', parentTitlebar.outerHeight() + offsetY);
            else
                uiWindow.css('top', offsetY);
        }
        uiWindow.width(tmpMaxWidth);
        uiWindow.height(tmpMaxHeight);
        var contentOffset = this.uiWindowContent.outerHeight()-this.uiWindowContent.height();
        this.uiWindowContent.height(tmpMaxHeight - this.uiWindowTitlebar.outerHeight() - contentOffset);
    },
    //--------------------------------------------------------------------
    minimize: function(){
        var options        = this.options;
        var uiWindow       = this.uiWindow;
        
        if( parseInt(options.winStyle & 1) != 0 )
        {
            if( this.uiWindowContent.is(':visible') )
            {
                this.normalHeightShow    = uiWindow.height();
                this.uiWindowContent.hide();
                uiWindow.height('auto');
                if( parseInt(options.winStyle & 2) != 0 )
                {
                    this.maxboxRightPos   = this.uiWindowTitlebarMaxBox.css('right');
                    this.uiWindowTitlebarMaxBox.css('right', this.uiWindowTitlebarMinBox.css('right'));
                    this.uiWindowTitlebarMinBox.css('right', this.maxboxRightPos);
                    this.uiWindowTitlebarMaxBox.hide();
                }
            }else{
                this.uiWindowContent.show();
                uiWindow.height(this.normalHeightShow);
                if( parseInt(options.winStyle & 2) != 0 )
                {
                    this.maxboxRightPos  = this.uiWindowTitlebarMinBox.css('right');
                    this.uiWindowTitlebarMinBox.css('right', this.uiWindowTitlebarMaxBox.css('right'));
                    this.uiWindowTitlebarMaxBox.css('right', this.maxboxRightPos);
                    this.uiWindowTitlebarMaxBox.show();
                }
            }
        }
    },
    //--------------------------------------------------------------------
    _makeDraggable: function(){
        var self = this,
            options = self.options,
            doc = $(document),
            heightBeforeDrag;

        function filteredUi(ui) {
            return {
                position: ui.position,
                offset: ui.offset
            };
        }
        
        self.uiWindow.draggable({
            //cancel: '.ui-window-content, .ui-window-titlebar-close',
            cancel: '.ui-window-titlebar-close, .ui-window-titlebar-minbox, .ui-window-titlebar-maxbox',
            handle: '.ui-window-titlebar',
            helper: "original",
            opacity: self.options.dragAlpha,
            containment: self.appendContainment != 'body' ? self.appendContainment : false,
            start: function(event, ui) {
                // delete the two line, for at dragging will not change size.
                //heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
                //$(this).height($(this).height()).addClass("ui-window-dragging");
                $(this).addClass("ui-window-dragging");
                self._trigger('dragStart', event, filteredUi(ui));
            },
            drag: function(event, ui) {
                self._trigger('drag', event, filteredUi(ui));
            },
            stop: function(event, ui) {
                options.position = [ui.position.left - doc.scrollLeft(),
                    ui.position.top - doc.scrollTop()];
                $(this).removeClass("ui-window-dragging");//.height(heightBeforeDrag);
                self._trigger('dragStop', event, filteredUi(ui));
            }
        });
    },
    //--------------------------------------------------------------------
    _makeResizable: function(handles){
        handles = (handles === undefined ? this.options.resizable : handles);
        var self = this,
            options = self.options,
            // .ui-resizable has position: relative defined in the stylesheet
            // but windows have to use absolute or fixed positioning
            position = self.uiWindow.css('position'),
            resizeHandles = (typeof handles === 'string' ?
                handles    :
                'n,e,s,w,se,sw,ne,nw'
            );

        function filteredUi(ui) {
            return {
                originalPosition: ui.originalPosition,
                originalSize: ui.originalSize,
                position: ui.position,
                size: ui.size
            };
        }

        self.uiWindow.resizable({
            //cancel: '.ui-window-content',
            containment: self.appendContainment != 'body' ? self.appendContainment : false,
            alsoResize: self.element,
            maxWidth: options.maxWidth,
            maxHeight: options.maxHeight,
            minWidth: options.minWidth,
            minHeight: self._minHeight(),
            handles: resizeHandles,
            start: function(event, ui) {
                $(this).addClass("ui-window-resizing");
                self._trigger('resizeStart', event, filteredUi(ui));
            },
            resize: function(event, ui) {
                self._trigger('resize', event, filteredUi(ui));
            },
            stop: function(event, ui) {
                $(this).removeClass("ui-window-resizing");
                options.height = $(this).height();
                options.width = $(this).width();
                self._trigger('resizeStop', event, filteredUi(ui));
            }
        })
        .css('position', position)
        .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
    },
    //--------------------------------------------------------------------
    _minHeight: function(){
        var options = this.options;

        if (options.height === 'auto') {
            return options.minHeight;
        } else {
            var tmpHeight   = options.height;
            if( typeof tmpHeight == 'string' && tmpHeight.substr(0, tmpHeight.length-1) == '%')
            {
                tmpHeight   = tmpHeight.substr(0, tmpHeight.length-1);
                if( isNaN(tmpHeight) )
                    tmpHeight   = options.minHeight;
                else
                    tmpHeight   = parseInt(tmpHeight) * 0.01;
                if( this.appendContainment == 'body' ){
                    tmpHeight   = $(window).height() * tmpHeight;
                }else{
                    tmpHeight   = this.uiWindow.parent().height() * tmpHeight;
                }
            }
            return Math.min(options.minHeight, parseInt(tmpHeight));
        }
    },
    //--------------------------------------------------------------------
    _setOption: function(key, value){
        var self = this,
            uiWindow = self.uiWindow,
            isResizable = uiWindow.is(':data(resizable)'),
            resize = false;
        
        switch (key) {
            case "styleClass":
                uiWindow
                    .removeClass(self.options.styleClass)
                    .addClass(uiWindowClasses + value);
                break;
            case "disabled":
                if (value) {
                    uiWindow.addClass('ui-window-disabled');
                } else {
                    uiWindow.removeClass('ui-window-disabled');
                }
                break;
            case "draggable":
                if (value) {
                    self._makeDraggable();
                } else {
                    uiWindow.draggable('destroy');
                }
                break;
            case "height":
                resize = true;
                break;
            case "maxHeight":
                if (isResizable) {
                    uiWindow.resizable('option', 'maxHeight', value);
                }
                resize = true;
                break;
            case "maxWidth":
                if (isResizable) {
                    uiWindow.resizable('option', 'maxWidth', value);
                }
                resize = true;
                break;
            case "minHeight":
                if (isResizable) {
                    uiWindow.resizable('option', 'minHeight', value);
                }
                resize = true;
                break;
            case "minWidth":
                if (isResizable) {
                    uiWindow.resizable('option', 'minWidth', value);
                }
                resize = true;
                break;
            case "position":
                self._position(value);
                break;
            case "resizable":
                // currently resizable, becoming non-resizable
                if (isResizable && !value) {
                    uiWindow.resizable('destroy');
                }

                // currently resizable, changing handles
                if (isResizable && typeof value === 'string') {
                    uiWindow.resizable('option', 'handles', value);
                }

                // currently non-resizable, becoming resizable
                if (!isResizable && value !== false) {
                    self._makeResizable(value);
                }
                break;
            case "title":
                // convert whatever was passed in o a string, for html() to not throw up
                $(".ui-window-title", self.uiWindowTitlebar).html("" + (value || '&#160;'));
                break;
            case "width":
                resize = true;
                break;
        }

        $.Widget.prototype._setOption.apply(self, arguments);
        if (resize) {
            self._size();
        }
    },
    //--------------------------------------------------------------------
    _size: function(){
        /* If the user has resized the window, the .ui-window and .ui-window-content
         * divs will both have width and height set, so we need to reset them
         */
        var options = this.options,
            nonContentHeight;

        // reset content sizing
        // hide for non content measurement because height: 0 doesn't work in IE quirks mode (see #4350)
        this.element.css({
            width: 'auto',
            minHeight: 0,
            height: 0
        });

        // reset wrapper sizing
        // determine the height of all the non-content elements
        var tmpWidth    = options.width;
        var tmpHeight   = options.height;
        var tmpMinHeight= 0;
        if( tmpWidth !== 'auto' )
        {
            if( typeof tmpWidth == 'string' && tmpWidth.substr(tmpWidth.length-1) == '%')
            {
                tmpWidth   = tmpWidth.substr(0, tmpWidth.length-1);
                if( isNaN(tmpWidth) )
                    tmpWidth   = options.tmpWidth;
                else
                    tmpWidth   = parseInt(tmpWidth) * 0.01;
                
                if( this.appendContainment == 'body' )
                {
                    tmpWidth    = $(window).width() * tmpWidth;
                }else{
                    tmpWidth    = this.uiWindow.parent().width() * tmpWidth;
                }
            }else{
                tmpWidth    = parseInt(tmpWidth);
                if( tmpWidth < options.minWidth ){
                    tmpWidth    = options.minWidth;
                }else if( options.maxWidth && tmpWidth > options.maxWidth ){
                    tmpWidth    = options.maxWidth;
                }
            }
            tmpWidth = tmpWidth - (this.uiWindow.outerWidth() - this.uiWindow.width());
        }
        nonContentHeight = this.uiWindow.css({
            height: 'auto', 
            width: tmpWidth
        }).outerHeight();
        
        if( tmpHeight === 'auto' ){
            tmpMinHeight    = Math.max(options.minHeight - nonContentHeight, 0);
        }else{
            if( typeof tmpHeight == 'string' && tmpHeight.substr(tmpHeight.length-1) == '%')
            {
                tmpHeight   = tmpHeight.substr(0, tmpHeight.length-1);
                if( isNaN(tmpHeight) )
                    tmpHeight   = options.minHeight;
                else
                    tmpHeight   = parseInt(tmpHeight) * 0.01;
                    
                if( this.appendContainment == 'body' ){
                    tmpHeight   = $(window).height() * tmpHeight;
                }else{
                    tmpHeight   = this.uiWindow.parent().height() * tmpHeight;
                }
            }
            tmpHeight    = Math.max(parseInt(tmpHeight) - nonContentHeight, 0);
            tmpMinHeight = 0; 
        }
        this.element
            .css({ 
                minHeight: tmpMinHeight, 
                height: tmpHeight
            });//.show();

        if (this.uiWindow.is(':data(resizable)')) {
            this.uiWindow.resizable('option', 'minHeight', this._minHeight());
        }
    },
    //--------------------------------------------------------------------
    _position: function(position) {
        var myAt = [],
            offset = [0, 0],
            isVisible;

        position = position || $.ui.window.prototype.options.position;

        if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
            myAt = position.split ? position.split(' ') : [position[0], position[1]];
            if (myAt.length === 1) {
                myAt[1] = myAt[0];
            }

            $.each(['left', 'top'], function(i, offsetPosition) {
                if (+myAt[i] === myAt[i]) {
                    offset[i] = myAt[i];
                    myAt[i] = offsetPosition;
                }
            });
        } else if (typeof position === 'object') {
            if ('left' in position) {
                myAt[0] = 'left';
                offset[0] = position.left;
            } else if ('right' in position) {
                myAt[0] = 'right';
                offset[0] = -position.right;
            }

            if ('top' in position) {
                myAt[1] = 'top';
                offset[1] = position.top;
            } else if ('bottom' in position) {
                myAt[1] = 'bottom';
                offset[1] = -position.bottom;
            }
        }
        
        if( offset[0] > this.uiWindow.parent().width() - this.uiWindow.width()){
            offset[0]  =  this.uiWindow.parent().width()- this.uiWindow.width();
        }
        
        if( offset[1] > this.uiWindow.parent().height() - this.uiWindow.height()){
            offset[1]  =  this.uiWindow.parent().height()- this.uiWindow.height();
        }

        // need to show the window to get the actual offset in the position plugin
        isVisible = this.uiWindow.is(':visible');
        if (!isVisible) {
            this.uiWindow.show();
        }
        var self    = this;
        this.uiWindow
            // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
            .css({ top: 0, left: 0 })
            .position({
                my: myAt.join(' '),
                at: myAt.join(' '),
                offset: offset.join(' '),
                of: window,
                collision: 'none',
                // ensure that the titlebar is never outside the document
                using: function(pos) {
                    var leftOffset = $(this).css(pos).offset().left;
                    if (leftOffset < 0) {
                        $(this).css('left', pos.left - leftOffset);
                    }
                    var topOffset = $(this).css(pos).offset().top;
                    if (topOffset < 0) {
                        $(this).css('top', pos.top - topOffset);
                    }
                }
            });
        if (!isVisible) {
            this.uiWindow.hide();
        }
    },
    //--------------------------------------------------------------------
    setAttributes: function(attributes)
    {
        if(attributes.align){
            this.options.position   = attributes.align;
            this._position(this.options.position);
        }else if( attributes.posX && attributes.posY ){
            this.options.position   = [attributes.posX, attributes.posY];
            this._position(this.options.position);
        }else if(attributes.posX && this.uiWindow.position.left != attributes.posX){
            this.options.position   = [attributes.posX, this.uiWindow.position.top];
            this._position(this.options.position);
        }else if(attributes.posY && this.uiWindow.position.top != attributes.posY){
            this.options.position   = [this.uiWindow.position.left, attributes.posY];
            this._position(this.options.position);
        }
        if( attributes.title ){
            this.uiWindowTitle.html(attributes.title);
        }
    }
});

$.extend($.ui.window, {
    version: "1.0.0",
    uuid: 0,
    maxZ: 0,
    getTitleId: function($el) {
        var id = $el.attr('id');
        if (!id) {
            this.uuid += 1;
            id = this.uuid;
        }
        return 'ui-window-title-' + id;
    }
});

}(jQuery));